package week3;

import jsjf.DequeADT;
import jsjf.LinearNode1;
import jsjf.exceptions.EmptyCollectionException;

public class LinkedDeque<T>implements DequeADT<T> {
    private LinearNode1<T> front,rear;
    int count;

    public LinkedDeque(){
        count = 0;
        front = rear = null;
    }
    @Override
    public void enqueueLast(T element) {
        LinearNode1<T> node = new LinearNode1<T>(element);

        if (isEmpty())
        {
            rear = node;
        }
        else
        {
            rear.setNext(node);
        }
        node.setPrevious(rear);
        rear = node;

        count++;
    }

    @Override
    public T dequeueLast() throws EmptyCollectionException {
        if (isEmpty())
        {
            throw new EmptyCollectionException("queue");
        }

        LinearNode1<T> temp = rear;
        rear = rear.getPrevious();

        T result = temp.getElement();
        if (!isEmpty())
        {
            rear.setNext(null);
        }
        else
        {
            front = null;
        }
        count--;
        return result;
    }

    @Override
    public void enqueueFirst(T element) {
        LinearNode1<T> node = new LinearNode1<T>(element);

        if (isEmpty())
        {
            front = node;
        }
        else
        {
            front.setPrevious(node);
        }
        node.setNext(front);
        front = node;

        count++;
    }

    @Override
    public T dequeueFirst() {
        if (isEmpty())
            return null;
        LinearNode1<T> temp = front;
        front = front.getNext();
        if (front!= null)
        {
            front.setPrevious(null);
        }
        else {
            rear = null;
        }
        T result = temp.getElement();
        return result;
    }

    @Override
    public T first() {
        if(isEmpty())
            throw new EmptyCollectionException("queue");

        return front.getElement();
    }

    @Override
    public T last() {
        if(isEmpty())
            throw new EmptyCollectionException("queue");

        return rear.getElement();
    }

    @Override
    public boolean isEmpty() {
        if (count == 0)
        {
            return true;
        }
        else
            return false;
    }

    @Override
    public int size() {
        return count;
    }

    public String toString()
    {
        String result = "";
        LinearNode1 temp = front;
        while (temp != null)
        {
            result += temp.getElement() + "";
            temp = temp.getNext();
        }
        return result;
    }
}
